#include "handlers/http_handler.hpp"
#include "database/user_dao.hpp"
#include "utils/crypto.hpp"
#include "utils/token.hpp"
#include "utils/service_discovery.hpp"
#include "common/response.hpp"
#include "common/config.hpp"
#include "models/user.hpp"
#include "protos/user_service.grpc.pb.h"
#include <workflow/HttpUtil.h>
#include <nlohmann/json.hpp> 
#include <iostream>     
#include <grpc++/grpc++.h>

using namespace cloud::storage;

using json = nlohmann::json;

// --- 用户注册 ---
void HttpHandlers::handleSignup(WFHttpTask *task) {
    const void* body;
    size_t size;
    task->get_req()->get_parsed_body(&body, &size);

    try {
        json req_json = json::parse(static_cast<const char*>(body), static_cast<const char*>(body) + size);
        std::string username = req_json.at("username");
        std::string password = req_json.at("password");

        // 服务发现：找到一个可用的UserService
        ServiceDiscovery discovery(Config::CONSUL_URI);
        std::string service_addr = discovery.discoverService("UserService");
        if (service_addr.empty()) {
            task->get_resp()->set_status_code("503");
            task->get_resp()->append_output_body(Response::jsonError("UserService is currently unavailable."));
            return;
        }

        // 创建 gRPC 客户端并发起 RPC 调用
        auto channel = grpc::CreateChannel(service_addr, grpc::InsecureChannelCredentials());
        auto stub = UserService::NewStub(channel);
    
        SignupRequest req;
        req.set_username(username);
        req.set_password(password); 

        SignupResponse resp;
        grpc::ClientContext context;

        grpc::Status status = stub->Signup(&context, req, &resp);

        // 将 RPC 响应转换为 HTTP 响应
        if (status.ok() && resp.code() == 0) {
            task->get_resp()->append_output_body(Response::jsonSuccess({{"message", resp.message()}}));
        } else {
            task->get_resp()->append_output_body(Response::jsonError(resp.message()));
        }

    } catch (const json::exception& e) {
        task->get_resp()->set_status_code("400");
        task->get_resp()->append_output_body(Response::jsonError("Invalid JSON format or missing fields."));
    }
}

// --- 用户登录 ---
void HttpHandlers::handleSignin(WFHttpTask *task) {
    const void* body;
    size_t size;
    task->get_req()->get_parsed_body(&body, &size);

    try {
        json req_json = json::parse(static_cast<const char*>(body), static_cast<const char*>(body) + size);
        std::string username = req_json.at("username");
        std::string password = req_json.at("password");

        // 服务发现
        ServiceDiscovery discovery(Config::CONSUL_URI);
        std::string service_addr = discovery.discoverService("UserService");
        if (service_addr.empty()) {
            task->get_resp()->append_output_body(Response::jsonError("UserService not available."));
            return;
        } 

        // 创建gPRC 客户端并发起调用
        auto channel = grpc::CreateChannel(service_addr, grpc::InsecureChannelCredentials());
        auto stub = UserService::NewStub(channel);

        SigninRequest req;
        req.set_username(username);
        req.set_password(password);
        SigninResponse resp;
        grpc::ClientContext context;

        grpc::Status status = stub->Signin(&context, req, &resp);

        if (status.ok() && resp.code() == 0) { 
            json data;
            data["token"] = resp.token();
            data["username"] = username;
            task->get_resp()->append_output_body(Response::jsonSuccess(data));
        }
        else {
            task->get_resp()->set_status_code("401");
            task->get_resp()->append_output_body(Response::jsonError("Invalid username or password."));
        }

    } catch (const json::exception& e) {
        task->get_resp()->append_output_body(Response::jsonError("Invalid JSON format or missing fields."));
        task->get_resp()->set_status_code("400");
    }
}

// --- 获取用户信息 ---
void HttpHandlers::handleGetUserInfo(WFHttpTask *task) {
    const auto* req = task->get_req();
    protocol::HttpHeaderCursor cursor(req);
    std::string auth_header;
    std::string token;

    if (cursor.find("Authorization", auth_header) && auth_header.rfind("Bearer ", 0) == 0) {
        token = auth_header.substr(7);
    }

    if (token.empty()) {
        task->get_resp()->set_status_code("401");
        task->get_resp()->append_output_body(Response::jsonError("Authorization header is missing or invalid."));
        return;
    }

    ServiceDiscovery discovery(Config::CONSUL_URI);
    std::string service_addr = discovery.discoverService("UserService");
    if (service_addr.empty()) {
        task->get_resp()->append_output_body(Response::jsonError("UserService not available."));
        return;
    }

    auto channel = grpc::CreateChannel(service_addr, grpc::InsecureChannelCredentials());
    auto stub = UserService::NewStub(channel);

    UserInfoRequest uif_req;
    uif_req.set_token(token);

    UserInfoResponse uif_resp;
    grpc::ClientContext context;

    grpc::Status status = stub->GetUserInfo(&context, uif_req, &uif_resp);


    if (status.ok() && uif_resp.code() == 0) {
        json user_info;
        user_info["username"] = uif_resp.username();
        user_info["signup_at"] = uif_resp.signup_at();

        task->get_resp()->append_output_body(Response::jsonSuccess(user_info));
        task->get_resp()->set_status_code("200");
    }
    else {
        task->get_resp()->append_output_body(Response::jsonError(uif_resp.message()));
    }
}

// --- 通用处理器 ---
void HttpHandlers::handleNotFound(WFHttpTask *task) {
    task->get_resp()->set_status_code("404");
    task->get_resp()->append_output_body(Response::jsonError("Not Found"));
}

void HttpHandlers::handleRoot(WFHttpTask *task) {
    task->get_resp()->set_status_code("302");
    task->get_resp()->add_header_pair("Location", "/static/view/login.html");
}
